/**
 * Created by jianglinjie on Thu Sep 28 2017
 * @flow
 */
'use strict';

import type {
  ModifyPassParam,
  ModifyPassResult,
  ResetPasswordParam,
  ResetPasswordResult,
} from '../../types';
import { createError } from '../../utils/ErrorUtils';
import { ErrorCode } from '../../constants';
import { User } from '../../db/models';
import hasha from 'hasha';
import { getCaptchaRedisKey } from '../../utils/CaptchaUtils';
import redis from '../../redis';
import { isPhone, checkPass } from '../../utils/CheckUtils';
import { CaptchaBusiness } from '../../constants';
import { logger } from '../../utils/LoggerUtils';

class PasswordService {
  async resetPassword(param: ResetPasswordParam): Promise<ResetPasswordResult> {
    if (!isPhone(param.phone)) {
      throw createError(400, '手机号非法', ErrorCode.PHONE_INVALID);      
    }

    if (!param.captcha) {
      throw createError(400, '缺少验证码', ErrorCode.REQUIRE_CAPTCHA);            
    }

    if (!checkPass(param.newPass)) {
      throw createError(400, '密码非法', ErrorCode.PASSWORD_INVALID);            
    }

    let redisKey = getCaptchaRedisKey(param.phone, CaptchaBusiness.RESET_PASSWORD);
    let captcha = await redis.getAsync(redisKey);
    if (captcha !== param.captcha) {
      throw createError(400, '验证码失效，请重新获取验证码', ErrorCode.CAPTCHA_INVALID);                          
    }

    redis.delAsync(redisKey).catch(delErr => {
      logger.error('redis delete redisKey %s error', redisKey, delErr);
    });

    let userDoc = await User.findOne({ phone: param.phone });
    if (userDoc) {
      //更新密码和修改时间
      userDoc.pwd = param.newPass;
      userDoc.encryptPwd = hasha(param.newPass, { algorithm: 'md5' });
      userDoc.pwdModifyTime = Date.now();
      
      //将更新保存到数据库中
      await userDoc.save();

      return {
        modifyTime: userDoc.pwdModifyTime.getTime(),
      };
    } else {
      throw createError(400, '手机号未注册', ErrorCode.PHONE_NOT_EXIST);                  
    }
  }

  async modify(param: ModifyPassParam): Promise<ModifyPassResult> {
    if (!checkPass(param.oldPass)) {
      throw createError(400, '旧密码非法', ErrorCode.PASSWORD_INVALID);
    }

    if (!checkPass(param.newPass)) {
      throw createError(400, '新密码非法', ErrorCode.PASSWORD_INVALID);      
    }

    if (param.oldPass === param.newPass) {
      throw createError(400, '密码相同', ErrorCode.PASSWORD_NOT_CHANGE);      
    }

    let userDoc = await User.findById(param.uid);
    if (userDoc) {
      if (userDoc.pwd !== param.oldPass) {
        throw createError(400, '密码错误', ErrorCode.PWD_ERROR);        
      }

      userDoc.pwd = param.newPass;
      userDoc.encryptPwd = hasha(param.newPass, { algorithm: 'md5' });
      userDoc.pwdModifyTime = Date.now();
      await userDoc.save();

      return {
        modifyTime: userDoc.pwdModifyTime.getTime()
      };
    } else {
      throw createError(400, '用户不存在', ErrorCode.USER_NOT_EXIST);
    }
  }
}

export default new PasswordService();